package com.egao.common.core.security;

import com.alibaba.fastjson.JSON;
import com.egao.common.core.Constants;
import com.egao.common.core.web.JsonResult;
import com.egao.common.system.entity.LoginRecord;
import com.egao.common.system.entity.Menu;
import com.egao.common.system.entity.User;
import com.egao.common.system.service.LoginRecordService;
import com.egao.common.system.service.UserService;
import com.egao.gps.entity.UserLoginTimes;
import com.egao.gps.service.UserLoginTimesService;
import com.egao.orderB.entity.Customer;
import com.egao.orderB.entity.Driver;
import com.egao.orderB.service.CustomerService;
import com.egao.orderB.service.DriverService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

/**
 * 登录过滤器
 * Created by wangfan on 2020-03-24 12:57
 */
public class JwtLoginFilter extends UsernamePasswordAuthenticationFilter {
    @Autowired
    private LoginRecordService loginRecordService;
    @Autowired
    private UserService userService;
    @Autowired
    private DriverService driverService;
    @Autowired
    private CustomerService customerService;
    @Autowired
    private UserLoginTimesService userLoginTimesService;

    public JwtLoginFilter(AuthenticationManager authenticationManager) {
        super.setAuthenticationManager(authenticationManager);
        super.setFilterProcessesUrl("/api/nt/login");
    }

    /**
     * 登录成功签发token返回json数据
     */
    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult)
            throws IOException, ServletException {
        UserDetails user = (UserDetails) authResult.getPrincipal();
        User user2 = userService.getUserByUsername(new User(user.getUsername()));
        user2.setRoles(userService.getRoleIdsByUserId(user2));

        Driver driver = new Driver();
        driver.setId(user2.getCustomerId()+"");
        Customer customer = new Customer();
        customer.setId(user2.getCustomerId()+"");
        if(user2.getType().equals("司机")){
            driver = driverService.getById(driver);
        } else if(user2.getType().equals("货代")){
            customer = customerService.getById(customer);
        }
        String access_token = JwtUtil.buildToken(user.getUsername(), Constants.TOKEN_EXPIRE_TIME, Constants.TOKEN_KEY);
        // 记录登录日志
        loginRecordService.saveAsync(user.getUsername(), request);
        StringBuffer permissionStr = new StringBuffer("");
        List<Menu> permission = userService.apiGetMenuByUser(user2);
        boolean pc = false;
        if(permission != null && permission.size() > 0) {
            for (Menu m : permission) {
                if(m==null || m.getAuthority()==null){
                    continue;
                }
                if(m.getAuthority().equals("")){
                    continue;
                }
                if(pc){
                    permissionStr.append(",");
                }
                permissionStr.append(m.getAuthority());
                pc = true;
            }
        }

        // 返回json数据
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.write(JSON.toJSONString(JsonResult.ok("登录成功").put("access_token", access_token)
                .put("token_type", JwtUtil.TOKEN_TYPE)
                .put("user", user2)
                .put("driver", driver)
                .put("customer", customer)
                .put("permission", permissionStr)));
        out.flush();
    }

    /**
     * 登录失败处理
     */
    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
        String username = request.getParameter("username");
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter out = response.getWriter();
        JsonResult result;
        if (e instanceof UsernameNotFoundException) {
            result = JsonResult.error("账号不存在");
            loginRecordService.saveAsync(username, LoginRecord.TYPE_ERROR, "账号不存在", request);
        } else if (e instanceof BadCredentialsException) {
            result = JsonResult.error("密码错误");
            loginRecordService.saveAsync(username, LoginRecord.TYPE_ERROR, "密码错误", request);
            UserLoginTimes userLoginTimes = new UserLoginTimes();
            userLoginTimes.setUsername(username);
            if(!userLoginTimesService.judgeLoginTimes(userLoginTimes)) {
                result = JsonResult.error("密码输入错误3次,账号已冻结,请联系管理解冻!");
            }
        } else if (e instanceof LockedException) {
            result = JsonResult.error("账号被锁定");
            loginRecordService.saveAsync(username, LoginRecord.TYPE_ERROR, "账号被锁定", request);
        }  else if (e.getMessage().equals("Incorrect result size: expected 1, actual 0")) {
            result = JsonResult.error("帐号未审核或未注册");
            loginRecordService.saveAsync(username, LoginRecord.TYPE_ERROR, "帐号未审核", request);
        } else {
            result = JsonResult.error(e.getMessage());
        }
        out.write(JSON.toJSONString(result));
        out.flush();
    }

}
